Skip to main content

Creating Git Submodules

Objective: Create Project B within Project A, and introduce Project B as an independent repository into Project A through git submodule.


I. Why Use Submodules

The core reasons for using git submodule are:

  • Project B can be developed and released independently
  • Project A only references a specific version of B
  • Multiple projects can reuse the same B
  • Avoid putting all code into a single repository (pseudo monorepo)

Suitable scenarios:

  • SDK / utility libraries
  • Base components
  • Modules requiring independent CI / release

II. Overall Process Overview

  1. Create Project B directory in Project A
  2. Initialize Project B as an independent Git repository
  3. Use gh to create remote repository and push
  4. Add Project B as a submodule back to Project A
  5. Commit the submodule changes in Project A

III. Creating Project B in Project A

Enter the root directory of Project A:

cd A-project

Create Project B directory (example):

mkdir -p packages/B-project
cd packages/B-project

IV. Initialize Project B Repository

1. Initialize Git

git init

2. Create Initial Commit (Required)

echo "# B-project" > README.md
git add .
git commit -m "chore: initial commit"

⚠️ Submodule cannot reference a repository without commits


V. Create Remote Repository Using GitHub CLI

Ensure you are logged into GitHub:

gh auth status

Create and push repository (compatible with fish / bash):

gh repo create B-project --private --source=. --remote=origin --push

If it's a public repository, change --private to --public

Verify remote repository:

git remote -v

VI. Add Project B as a Submodule to Project A

1. Return to Project A Root Directory

cd ../../

2. Delete Local B Directory (Critical Step)

rm -rf packages/B-project

⚠️ Submodule will clone the repository itself; the local directory must be empty


3. Add Submodule

git submodule add https://github.com/<username-or-organization>/B-project.git packages/B-project

After success, the following will be generated:

  • packages/B-project/
  • .gitmodules

VII. Commit Submodule Changes in Project A

git add .gitmodules packages/B-project
git commit -m "chore: add B-project as submodule"
git push

VIII. Daily Development and Update Workflow

1. Develop Project B

cd packages/B-project
git checkout main

Modify and commit:

git add .
git commit -m "feat: xxx"
git push

2. Update Submodule Version in Project A

cd ../../
git status

You will see:

modified: packages/B-project (new commits)

Commit the update:

git add packages/B-project
git commit -m "chore: bump B-project submodule"
git push

IX. Clone Projects with Submodules

git clone --recurse-submodules <A-project-repo>

Pull Submodules for Already Cloned Project

git submodule update --init --recursive

X. Common Pitfalls Summary

❌ Forgot to Make Initial Commit for Project B

→ Submodule cannot be added

❌ Did Not Delete Local Directory Before Adding Submodule

already exists and is not a git repository

❌ Updated B but Did Not Commit A's Submodule Pointer

→ Others cannot pull the latest version


XI. Additional Recommendations

  • Consistently place submodules in packages/ or libs/ directory
  • Submodule updates must have separate commits
  • Team agreement: Prohibit directly modifying submodule's detached HEAD

Conclusion: Submodule manages "dependency commits", not the code itself. Once you clarify "who is responsible for publishing and who is responsible for referencing", you won't step into pitfalls.


If you'd like, I can also help you convert this note into:

  • Team standards version
  • Simplified README version
  • Version with flowcharts